package com.seres.backend;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import com.seres.data.Ace;
import com.seres.data.Answer;
import com.seres.data.DataManager;
import com.seres.data.Index;
import com.seres.data.IndexImpact;
import com.seres.data.Stakeholder;
import com.seres.data.StakeholderImpact;
import com.seres.events.DecisionEvent;
import com.seres.events.GameStateEvent;
import com.seres.general.EventBroker;

public class GameRecoveryManager {
	private String recoveryFilePathName;
	private File recoveryFile;
	private String answerString = "Answer";
	private String aceString = "Ace";
	private String delimiter = ":";
	
	private DataManager dataManager;
	
	public GameRecoveryManager(){
		setRecoveryFilePathName("gamerecovery.txt");
		setRecoveryFile(new File(getRecoveryFilePathName()));
		setDataManager(new DataManager());
	}
	
	public static void main(String[] args){
		GameRecoveryManager grm = new GameRecoveryManager();
    	Answer answer = new Answer("","",null,null,false,false,null);
    	Ace ace = new Ace("", "", null, null);
    	ace.setAceId(15);
    	answer.setAnswerId(10);
    	AnswerDecision decision = new AnswerDecision(answer);
    	CorrectiveDecision corDecision = new CorrectiveDecision(ace);
		grm.storeDecision(decision);
		grm.storeDecision(corDecision);
		List<String> lines = grm.readLines();
		grm.printLines(lines);
		
//		for(String line : lines){
//			grm.parseLine(line);
//		}
//		grm.deleteRecoveryFile();

	}
	
	public void storeDecision(AnswerDecision answerDecision){
		try {
			writeLine(getAnswerString() + getDelimiter() + answerDecision.getAnswer().getAnswerId());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void storeDecision(CorrectiveDecision correctiveDecision){
		try {
			writeLine(getAceString() + getDelimiter() + correctiveDecision.getAce().getAceId());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	private void writeLine(String line) throws IOException{
		BufferedWriter writer = null;

		try {
			writer = new BufferedWriter(new FileWriter(getRecoveryFilePathName(),true));
			writer.write(line);
			writer.newLine();
			
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		finally{
			writer.close();
		}
	}
	private List<String> readLines(){
		BufferedReader reader = null;
		List<String> lines = new ArrayList<String>();
		
		try {
			reader = new BufferedReader(new FileReader(getRecoveryFilePathName()));
			String line;
			while((line = reader.readLine()) != null){
				lines.add(line);
			}
			reader.close();
			
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
//			e.printStackTrace();
			System.out.println("no recovery file found!");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return lines;
	}
	public boolean canFindStoredGameState(){
		return readLines().size() > 0;
	}
	private void parseLine(String line){
		String[] parts = line.split(getDelimiter());
		
		if(parts[0].equals(getAceString())){
			performCorrectiveDecision(Integer.parseInt(parts[1]));
		}
		else if(parts[0].equals(getAnswerString())){
			performAnswerDecision(Integer.parseInt(parts[1]));
		}

	}
	private void performAnswerDecision(int answerId) {
//		System.out.println("answerId: " + answerId);
		
		Answer answer = null;
		
		if(answerId == 0){
        	// leeg antwoord & decision als tijdelijke workaround om scenario zonder antwoord op te vangen
    		ArrayList<IndexImpact> indexImpacts = new ArrayList<IndexImpact>();
//    		indexImpacts.add(new IndexImpact(0,Index.RISK));
    		//new implementation due to database changes for class stakeholder and indices
    		for(Index i : getDataManager().readAllIndices()){
    			indexImpacts.add(new IndexImpact(0, i));
    		}
    		
    		ArrayList<StakeholderImpact> stakeholderImpacts = new ArrayList<StakeholderImpact>();
//    		stakeholderImpacts.add(new StakeholderImpact(0,Stakeholder.AUTHORITIES));
//    		stakeholderImpacts.add(new StakeholderImpact(0,Stakeholder.CLINICIANS));
//    		stakeholderImpacts.add(new StakeholderImpact(0,Stakeholder.EMPLOYEES));
//    		stakeholderImpacts.add(new StakeholderImpact(0,Stakeholder.INTERNAL_PEERS));
//    		stakeholderImpacts.add(new StakeholderImpact(0,Stakeholder.KOLS));
//    		stakeholderImpacts.add(new StakeholderImpact(0,Stakeholder.PRESS));
//    		stakeholderImpacts.add(new StakeholderImpact(0,Stakeholder.PROF_SOCIETIES));
//    		stakeholderImpacts.add(new StakeholderImpact(0,Stakeholder.SMCIES));
    		//new implementation due to database changes for class stakeholder and indices
    		for(Stakeholder s: getDataManager().readAllStakeholders()){
    			stakeholderImpacts.add(new StakeholderImpact(0, s));
    		}
    		
        	answer = new Answer("","",indexImpacts,stakeholderImpacts,false,false,null);
		}
		else{
			answer = getDataManager().readAnswer(answerId);			
		}

		EventBroker.getEventBroker().fireDecisionEvent(new DecisionEvent(new AnswerDecision(answer)));
	}

	private void performCorrectiveDecision(int aceId) {
		System.out.println("aceId: " + aceId);
		Ace ace = getDataManager().readAce(aceId);
		EventBroker.getEventBroker().fireDecisionEvent(new DecisionEvent(new CorrectiveDecision(ace)));
	}

	private void printLines(List<String> lines){
		for(String line: lines){
			System.out.println(line);
		}
	}
	public void recoverGame(){
		EventBroker.getEventBroker().fireGameStateEvent(new GameStateEvent(GameState.START_NEXT_ACTION));
		List<String> lines = readLines();
		System.out.println("GameRecoveryManager: recoverGame: aantal lijnen: " + lines.size());
		deleteRecoveryFile();
		for(String line : lines){
			parseLine(line);
			EventBroker.getEventBroker().fireGameStateEvent(new GameStateEvent(GameState.START_NEXT_ACTION));
		}
	}
	public void deleteRecoveryFile(){
		getRecoveryFile().delete();
	}

	public String getRecoveryFilePathName() {
		return recoveryFilePathName;
	}

	public void setRecoveryFilePathName(String recoveryFilePathName) {
		this.recoveryFilePathName = recoveryFilePathName;
	}

	private File getRecoveryFile() {
		return recoveryFile;
	}

	private void setRecoveryFile(File recoveryFile) {
		this.recoveryFile = recoveryFile;
	}

	private String getAnswerString() {
		return answerString;
	}

	private void setAnswerString(String answerString) {
		this.answerString = answerString;
	}

	private String getAceString() {
		return aceString;
	}

	private void setAceString(String aceString) {
		this.aceString = aceString;
	}

	private String getDelimiter() {
		return delimiter;
	}

	private void setDelimiter(String delimiter) {
		this.delimiter = delimiter;
	}

	private void setDataManager(DataManager dataManager) {
		this.dataManager = dataManager;
	}

	private DataManager getDataManager() {
		return dataManager;
	}
}
